package wt.rocket.ctrl;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.*;

/**
 * controlador de la barra de menú asociado a la vista Menu.zul
 *
 * @author Waytech
 */
public class CtrlMenu extends GenericForwardComposer {

  //referencias:
  Include vistaBarraMenu;
  Include panelCentral;
  //widgets:
  Label etqStatus;
  Div divStatus;
  Menu tbbUsuario;
  Toolbarbutton btnRefresh;
  Toolbarbutton btnNew;
  Toolbarbutton btnEdit;
  Toolbarbutton btnSave;
  Toolbarbutton btnDelete;
  Toolbarbutton btnPrint;
  //variables de control:  
  String vistaActual;
  String vistaSiguiente;
  String modo;  //valores = {new,editar,ver,delete,listado,imprimir,operacion}

  @Override
  public void doAfterCompose(Component comp) throws Exception {
    super.doAfterCompose(comp);
    inicio();
  }

  public void inicio() throws InterruptedException {
    //OJO
    Sesion.setVistaBarraMenu(vistaBarraMenu);
    //* Sesion.setVistaActual(panelCentral.getSrc());
    mostrarNombreUsuario();
    //* System.out.println("CtrlMenu.inicio(): panelCentral.src=" + panelCentral.getSrc());
    iniciarBarraNavegacion();
  }

  public void logout() {
    System.out.println("CtrlBarraMenu:logout - antes de cerrar sesión");
    Sesion.setVariable("menu", null);
    Sesion.setVariable("idUsuario", null);
    Sesion.setVariable("usuarioLogueado", null);
    System.out.println("CtrlBarraMenu: - Sesión cerrada");
    Executions.sendRedirect("index.zul");
  }

  public void onClick$itemCerrarSesion(Event event) {
    logout();
  }

  void mostrarNombreUsuario() {
    String nombreUsuario = "";
    try {
      nombreUsuario = "" + Sesion.getVariable("nombreUsuario");
    } catch (Exception e) {
      System.out.println("CtrlSesion - ERROR de SESION: recuperando 'nombreUsuario'");
    }
    if (nombreUsuario == null) {
      tbbUsuario.setLabel("");
      System.out.println("CtrlSesion - nombreUsuario=null");
    } else {
      System.out.println("CtrlSesion - nombreUsuario= " + nombreUsuario);
    }
    tbbUsuario.setLabel(nombreUsuario);
  }

  public void onClick$itemPersonaListado() {
    cambiarVista(Vistas.PERSONA_LISTADO);
  }

  public void onClick$itemPersonaNew() {
    Sesion.setModo("new");
    Sesion.setVistaSiguiente(Vistas.PERSONA);
    onClick$btnControl();//forzar cambio de vista
  }

  public void onClick$itemPersonaEspecificaVer() {
    Sesion.setModo(Modos.VER);
    Sesion.setVistaSiguiente(Vistas.PERSONA);
    onClick$btnControl();//forzar cambio de vista
  }

  //OJO
  /**
   * notifica los eventos de boton a la ventana abierta actualmente
   * ("nuevo","editar","guardar","eliminar") para que se ejecuten los métodos
   * correspondientes de la ventana puede ser btnNew, btnEdit, btnSave,
   * btnDelete, btnPrint, etc...
   */
  private void notificarEvento(String idBoton) {
    Toolbarbutton boton = (Toolbarbutton) panelCentral.getFellow(idBoton);
    //simular un click del boton indicado en la vista de datos actual
    Events.sendEvent("onClick", boton, null);
  }

  //OJO
  public void onClick$btnNew() {
    borrarVarSesionResultado();
    ocultarMensaje();
    //notificar evento a ventana actual:
    modo = Modos.NEW;
    Sesion.setModo(modo);
    notificarEvento("btnNew");
    actualizarEstadoBarra();
  }

  //OJO
  public void onClick$btnEdit() {
    ocultarMensaje();
    modo = Modos.EDITAR;
    Sesion.setModo(modo);
    notificarEvento("btnEdit");
    actualizarEstadoBarra();
    borrarVarSesionResultado();
  }

  //OJO
  /**
   * botón usado para guardar cambios: al crear y editar un registro. Llama al
   * correspondiente botón grabar de la vista que esté abierta
   */
  public void onClick$btnSave() {
    if (modo.equals(Modos.OPERACION)) {
      mensaje("En construcción");
    } else if (modo.equals(Modos.NEW) || modo.equals(Modos.EDITAR)) {
      //* System.out.println("CtrlMenu.modo=" + modo);
      notificarEvento("btnSave");
      //aquí va el procesamiento de los datos... por parte de la ventana correspondiente

      //validación de resultado de operación
      Integer resultado = (Integer) Sesion.getVariable("resultOperacion");
      if (resultado == null) {
        //no hay resultado de operación
        return;
      }
      if (resultado == 0) {
        //**
        System.out.println("CtrlMenu.btnSave.resultado=OK");
        mensaje("Datos guardados");
        mensajeExitoEspecifico();
        modo = Modos.VER;
        Sesion.setModo(modo);
        actualizarEstadoBarra();
      } else if (resultado.intValue() == 1) {
        System.out.println("CtrlMenu.btnSave.resultado Operacion=ERROR");
      }
      /*
       *
       */
    }
  }

  /**
   * muestra mensajes de éxito de las operaciones realizadas
   */
  private void mensajeExitoEspecifico() {
    String msj = "";
    if (modo.equals(Modos.NEW)) {
      if (vistaActual.equals(Vistas.PERSONA)) {
        msj = "Persona Registrada con éxito";
      }
    } else if (modo.equals(Modos.EDITAR)) {
      if (vistaActual.equals(Vistas.PERSONA)) {
        msj = "Persona Actualizada con éxito";
      }
    }
    mensaje(msj);
  }

  public void onClick$btnDelete() {
    String modo_tmp = modo;
    modo = "borrar";
    mensaje("Eliminar: En construcción");
    //...aquí va el procesamiento para borrar
    modo = modo_tmp;
  }

  public void onClick$btnPrint() {
    String modo_tmp = modo;
    modo = "imprimir";
    mensaje("Imprimir: En construcción");
    //...aquí va el procesamiento de imprimir
    modo = modo_tmp;
  }

  public void onClick$btnRefresh() {
    //*System.out.println("CtrlBarraNavegacion: se intenta refrescar la ventana");
    String tmp = panelCentral.getSrc();
    panelCentral.setSrc("");
    panelCentral.setSrc(tmp);
    ocultarMensaje();
  }

  public void iniciarBarraNavegacion() {
    if (modo == null) {
      modo = Modos.LISTADO;
    }
    //* mostrarVistaActual("CtrlMenu.inicio");
    actualizarModo();
    actualizarEstadoBarra();
  }

  /**
   * TODO - Mejora de código: evaluar cambiar este método o limitar a sólo
   * algunas vistas especiales
   *
   * @param vista
   */
  public void cambiarVista(String vista) {
    ocultarMensaje();
    //+ actualizarModo();
    Sesion.setVistaActual(vista);
    actualizarEstadoBarra();
    cambiarPanelCentral(vista);
  }

  /**
   * actualiza el 'modo' de acuerdo a la vista actual
   */
  /**
   * TODO: ajustar de acuerdo a los permisos del usuario
   */
  //TODO: quitar este método, usando los métodos notificarBarra y los métodos de CtrlVista
  public void actualizarModo() {
    vistaActual = Sesion.getVistaActual();
    if (vistaActual.equals(Vistas.CELULA_LISTADO)) {
      modo = Modos.LISTADO;
    } else if (vistaActual.equals(Vistas.CELULA)) {
      modo = Modos.VER;
    } else if (vistaActual.equals(Vistas.PERSONA)) {
      modo = Modos.VER;
    } else if (vistaActual.equals(Vistas.PERSONA_LISTADO)) {
      modo = Modos.LISTADO;
    } else if (vistaActual.equals(Vistas.CUENTA_CAMBIAR_EMAIL)) {
      modo = Modos.OPERACION;
    } else if (vistaActual.equals(Vistas.CUENTA_CAMBIAR_PASSWORD)) {
      modo = Modos.OPERACION;
    } else {
      modo = Modos.CONSULTA;
    }
  }

  /**
   * actualiza estados de botones, de acuerdo al valor de la variable 'modo'
   * mostrando y ocultando los botones según corresponda
   */
  public void actualizarEstadoBarra() {
    if (modo.equals(Modos.NEW)) {
      btnRefresh.setVisible(false);
      btnPrint.setVisible(false);
      btnNew.setVisible(false);
      btnEdit.setVisible(false);
      btnSave.setVisible(true);
      btnDelete.setVisible(false);
      //TODO: falta botón cancelar
    } else if (modo.equals(Modos.VER)) {
      btnRefresh.setVisible(true);
      btnPrint.setVisible(true);
      btnNew.setVisible(false);
      btnEdit.setVisible(true);
      btnSave.setVisible(false);
      btnDelete.setVisible(true);
    } else if (modo.equals(Modos.EDITAR)) {
      btnRefresh.setVisible(false);
      btnPrint.setVisible(false);
      btnNew.setVisible(false);
      btnEdit.setVisible(false);
      btnSave.setVisible(true);
      btnDelete.setVisible(false);
      //TODO: falta botón cancelar
    } else if (modo.equals(Modos.CONSULTA)) {
      btnRefresh.setVisible(true);
      btnPrint.setVisible(true);
      btnNew.setVisible(false);
      btnEdit.setVisible(false);
      btnSave.setVisible(false);
      btnDelete.setVisible(false);
    } else if (modo.equals(Modos.LISTADO)) {
      btnRefresh.setVisible(true);
      btnNew.setVisible(true);
      btnEdit.setVisible(false);
      btnSave.setVisible(false);
      btnDelete.setVisible(false);
      btnPrint.setVisible(true);
    } else if (modo.equals(Modos.OPERACION)) {
      btnRefresh.setVisible(false);
      btnPrint.setVisible(false);
      btnNew.setVisible(false);
      btnEdit.setVisible(false);
      btnSave.setVisible(true);
      btnDelete.setVisible(false);
      //TODO: falta botón cancelar
    }
  }

  /**
   * Recibe la notificación de las ventanas, para el cambio de vista indicado en
   * variable de sesión vistaSiguiente y modifica los estado de la barra
   * correspondiente a la nueva vista
   */
  public void onClick$btnControl() {
    vistaActual = Sesion.getVistaActual();
    vistaSiguiente = Sesion.getVistaSiguiente();
    modo = Sesion.getModo();
    //TODO: si vistaSiguiente es igual a vistaActual sólo simular un click al botón Refresh
    cambiarVista(vistaSiguiente);
  }

  /**
   * Recibe la notificación para cambios de estados desde
   * acuerdo a la vist. Instrucciones: Antes de llamar este método, el controlador
   * correspondiente debe setear la variable de sesión 'modo'
   */
  public void onClick$btnControl2() {
    vistaActual = Sesion.getVistaActual();
    modo = Sesion.getModo();
    actualizarEstadoBarra();
  }

  /**
   * cambia vista mostrada en el include 'panelCentral'
   *
   * @param vista
   */
  private void cambiarPanelCentral(String vista) {
    //esta línea permite refrescar la vista, por si la nueva es igual a la actual
    panelCentral.setSrc("");
    panelCentral.setSrc(vista);
  }

  private void borrarVarSesionResultado() {
    Sesion.setVariable("resultOperacion", null);
  }

  public void mensaje(String mensaje) {
    etqStatus.setValue(mensaje);
    etqStatus.setVisible(true);
    //-divStatus.setVisible(true);
  }

  public void ocultarMensaje() {
    etqStatus.setValue("");
    etqStatus.setVisible(false);
    //-divStatus.setVisible(false);
  }
}
